package com.ruoyi.system.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.JjzApplyLog;
import com.ruoyi.system.domain.SysCarInfo;
import com.ruoyi.system.domain.SysWxUser;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.mapper.JjzApplyLogMapper;
import com.ruoyi.system.mapper.JjzApplyMapper;
import com.ruoyi.system.service.IJjzApplyService;
import com.ruoyi.system.service.ISysCarInfoService;
import com.ruoyi.system.service.ISysWxUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class JjzApplyServiceImpl implements IJjzApplyService {
    private static final Logger log = LoggerFactory.getLogger(JjzApplyServiceImpl.class);


    @Autowired
    private JjzApplyMapper jjzApplyMapper;

    @Autowired
    private JjzApplyLogMapper jjzApplyLogMapper;

    @Autowired
    private ISysCarInfoService carInfoService;

    @Autowired
    private ISysWxUserService wxUserService;

    @Autowired
    private RedisCache redisCache;

    @Override
    public void jjzApply() {

        //处理过期的数据
        checkExpData();

        // 获取当前时间，判断过期时间等于当前时间+1天
        List<ApplyCarVo> carInfo = jjzApplyMapper.selectApplyUser();

        for (ApplyCarVo item : carInfo) {
            try {
                int n = (int) (Math.random() * 10);
                Thread.sleep(n * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //进行申请
            HashMap header = new HashMap();
            header.put("Authorization", item.getAuthorization());
            // 获取第三方用户数据
            JjzApplyVo vo = new JjzApplyVo();
            // 添加数据
           // vo.setApplyIdOld(item.getApplyId());
            vo.setVId(item.getVId());
            // 号牌号码
            vo.setHphm(item.getHphm());
            //驾驶人姓名
            vo.setJsrxm(item.getJsrxm());
            // 驾驶证号
            vo.setJszh(item.getJszh());
            vo.setJjzzl(item.getJjzzl());
            //地区
            vo.setArea(item.getArea());
            vo.setJjdq(item.getJjdq());
            vo.setXxdz(item.getXxdz());
            vo.setSqdzgdjd(item.getSqdzgdjd());
            vo.setSqdzgdwd(item.getSqdzgdwd());
//            vo.setJjlk(item.getJjlk());
            vo.setJjlkmc(item.getJjlkmc());
            vo.setHpzl(item.getHpzl());
            vo.setZjxxdz(item.getZjxxdz());
            vo.setZjxxdzgdjd(item.getSqdzgdjd());
            vo.setZjxxdzgdwd(item.getSqdzgdwd());
            vo.setJjdzgdjd(item.getSqdzgdjd());
            vo.setJjdzgdwd(item.getSqdzgdwd());

            //进京日期
            LocalDateTime twoDaysLater = LocalDateTime.now().plusDays(1);
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");

            vo.setJjrq(twoDaysLater.format(df));

            SysCarInfo sysCarInfo = new SysCarInfo();
            sysCarInfo.setJjrq(twoDaysLater);
            sysCarInfo.setHphm(item.getHphm());
            sysCarInfo.setApplyTime(LocalDateTime.now());

            String param = JSONObject.toJSONString(vo);
            log.info("请求参数: {} ", param);
            String body = HttpRequest.post(RuoYiConfig.getJjzPath()+"/pro/applyRecordController/insertApplyRecord").headerMap(header, true).body(param).execute().body();
           // String body = "{\"code\":500,\"msg\":\"审核未通过，请到进京证办证窗口咨询或办理\",\"data\":\"500\",\"from\":\"v2\"}";


            JSONObject jsonObject = JSONObject.parseObject(body);
            log.info("申请接口返回数据: {} ", JSONObject.toJSONString(jsonObject));
            Object code = (int) jsonObject.get("code");
            if (code.equals(200)) {
                // 存入reds 设置过期时间
                redisCache.setCacheObject("APPLY_"+item.getAuthorization(), item.getHphm(), 1, TimeUnit.HOURS);
            } else {
                String msg = (String)jsonObject.get("msg");
                if("每个用户同一时间只能为一辆机动车申请办理进京证。".equals(msg)){
                    checkApplyJjz(item.getAuthorization());
                }else {
                    log.error("申请失败：========================>>>>>>>     "+jsonObject.get("msg"));
                    // 记录失败结果
                    JjzApplyLog jjzApplyLog = new JjzApplyLog();
                    jjzApplyLog.setType(2);
                    jjzApplyLog.setUserName(item.getJsrxm());
                    jjzApplyLog.setWxUserId(item.getWxUserId());
                    jjzApplyLog.setMsg(msg);
                    jjzApplyLog.setApplyTime(new Date());
                    jjzApplyLog.setHphm(item.getHphm());
                    jjzApplyLogMapper.insertLog(jjzApplyLog);
                }
            }
            carInfoService.updateCarInfoByHphm(sysCarInfo);
        }

    }

    @Override
    public void doApply(Long id, String date){

        ApplyCarVo item = jjzApplyMapper.selectApplyUserById(id);
        //进行申请
        HashMap header = new HashMap();
        header.put("Authorization", item.getAuthorization());
        // 获取第三方用户数据
        JjzApplyVo vo = new JjzApplyVo();
        // 添加数据
        // vo.setApplyIdOld(item.getApplyId());
        vo.setVId(item.getVId());
        // 号牌号码
        vo.setHphm(item.getHphm());
        //驾驶人姓名
        vo.setJsrxm(item.getJsrxm());
        // 驾驶证号
        vo.setJszh(item.getJszh());
        //地区
        vo.setArea(item.getArea());
        vo.setJjdq(item.getJjdq());
        vo.setXxdz(item.getXxdz());
        vo.setSqdzgdjd(item.getSqdzgdjd());
        vo.setSqdzgdwd(item.getSqdzgdwd());
//        vo.setJjlk(item.getJjlk());
        vo.setJjlkmc(item.getJjlkmc());
        vo.setHpzl(item.getHpzl());
        vo.setJjzzl(item.getJjzzl());

        vo.setZjxxdz(item.getZjxxdz());
        vo.setZjxxdzgdjd(item.getSqdzgdjd());
        vo.setZjxxdzgdwd(item.getSqdzgdwd());
        vo.setJjdzgdjd(item.getSqdzgdjd());
        vo.setJjdzgdwd(item.getSqdzgdwd());


        //进京日期
//        LocalDateTime twoDaysLater = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        vo.setJjrq(date);

        SysCarInfo sysCarInfo = new SysCarInfo();
        sysCarInfo.setJjrq(LocalDate.parse(date).atStartOfDay());
        sysCarInfo.setHphm(item.getHphm());
        sysCarInfo.setApplyTime(LocalDateTime.now());
        carInfoService.updateCarInfoByHphm(sysCarInfo);

        String param = JSONObject.toJSONString(vo);
        log.info("请求参数: {} ", param);
        String body = HttpRequest.post(RuoYiConfig.getJjzPath()+"/pro/applyRecordController/insertApplyRecord").headerMap(header, true).body(param).execute().body();
        //String body = "{\"code\":500,\"msg\":\"审核未通过，请到进京证办证窗口咨询或办理\",\"data\":\"500\",\"from\":\"v2\"}";
        JSONObject jsonObject = JSONObject.parseObject(body);
        log.info("申请接口返回数据: {} ", JSONObject.toJSONString(jsonObject));
        Object code = (int) jsonObject.get("code");
        if (code.equals(200)) {
            // 存入reds 设置过期时间
            redisCache.setCacheObject("APPLY_"+item.getAuthorization(), item.getHphm(), 1, TimeUnit.HOURS);
        } else {
            // 如果成功 修改状态为审核中 失败发送提醒
            log.error("申请失败：========================>>>>>>>     "+jsonObject.get("msg"));
            throw new RuntimeException("申请失败");
        }
    }


    public void editNewData(Long carInfoId) {
        SysCarInfo carInfo= carInfoService.selectCarInfoById(carInfoId);
        if (ObjectUtil.isNotEmpty(carInfo)) {
            SysWxUser sysWxUser = wxUserService.selectWxUserById(carInfo.getWxUserId());
            JSONArray bzclxx = getStateList(sysWxUser.getAuthorization());
            for (Object o : bzclxx) {
                JSONObject jsonstr = JSONObject.parseObject(o.toString());
                String hphm = jsonstr.getString("hphm");
                if (hphm.equals(carInfo.getHphm())) {
                    List<JjzResVo> jjzResVos = JSONArray.parseArray(jsonstr.getString("bzxx"), JjzResVo.class);
                    for (JjzResVo jjzResVo : jjzResVos) {
                        SysCarInfo car = new SysCarInfo();
                        car.setId(carInfo.getId());
                        car.setVid(jjzResVo.getVid());
                        car.setApplyid(jjzResVo.getApplyId());
                        car.setJszh(jjzResVo.getJszh());
                        car.setJsrxm(jjzResVo.getJsrxm());
                        car.setApplyStatus(1);
                        //1 未生效 2 审核中 3 生效中
//                        if ("审核通过(生效中)".equals(jjzResVo.getBlztmc())) {
//                            car.setApplyStatus(3);
//                        } else if ("审核通过(审核中)".equals(jjzResVo.getBlztmc())) {
//                            car.setApplyStatus(2);
//                        } else {
//                            car.setApplyStatus(1);
//                        }

                        car.setApplyTime(jjzResVo.getSqsj());
                        car.setStartTime(jjzResVo.getYxqs());
                        car.setEndTime(jjzResVo.getYxqz());
                        car.setHpzl(jjzResVo.getHpzl());
                        car.setJjmd("06");
                        car.setJjmdmc("其它");
                        car.setJjzzl("02");
                        List<JjlkVo> jjlkList = getJjlkList("jjlk.json", JjlkVo.class);
                        int n = (int) (Math.random() * 62);
                        JjlkVo jjlk = jjlkList.get(n);
                        car.setJjlk(jjlk.getZdbm());
                        car.setJjlkmc(jjlk.getZdz());
                        List<JjdqVO> jjdqList = getJjlkList("jjdq.json", JjdqVO.class);
                        int t = (int) (Math.random() * jjdqList.size());
                        // 随机选地区
                        JjdqVO jjdqVO = jjdqList.get(t);
                        car.setJjdq(jjdqVO.getZdbm());
                        car.setArea(jjdqVO.getZdz());
                        // 随机选乡镇
                        int m = (int) (Math.random() * jjdqVO.getZdzj().size());
                        ZdzjVO zdzjVO = jjdqVO.getZdzj().get(m);
                        car.setXxdz("北京市"+zdzjVO.getZdz()+zdzjVO.getXxdz());
                        car.setZjxxdz(zdzjVO.getXxdz());
                        car.setSqdzgdwd(zdzjVO.getSqdzgdjd());
                        car.setSqdzgdjd(zdzjVO.getSqdzgdwd());
                        carInfoService.updateCarInfo(car);
                    }
                }
                //throw new RuntimeException("车牌号不正确！！");
            }
        }
    }

    @Override
    public void checkApplyJjz(String auth) {
        try {
            int n = (int) (Math.random() * 10);
            Thread.sleep(n * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        JSONArray bzclxx = getStateList(auth);
        for (Object o : bzclxx) {
            JSONObject jsonstr = JSONObject.parseObject(o.toString());
            List<JjzResVo> ecbzxxRes = JSONArray.parseArray(jsonstr.getString("ecbzxx"), JjzResVo.class);
            if(ecbzxxRes != null && ecbzxxRes.size() >0){
                for (JjzResVo jjzResVo : ecbzxxRes) {
                    //车牌号码
                    String hphm = jjzResVo.getHphm();
                    String blztmc = jjzResVo.getBlztmc();
                    //如果申请成功 修改状态为审核通过
                    if ("审核通过(待生效)".equals(blztmc)) {
                        SysCarInfo carInfo = new SysCarInfo();
                        carInfo.setHphm(hphm);
                        carInfo.setYxqs(jjzResVo.getYxqs());
                        carInfo.setYxqz(jjzResVo.getYxqz());
                        carInfo.setApplyStatus(1);
                        carInfoService.updateCarInfoByHphm(carInfo);
                    }
                    if ("失败(审核不通过)".equals(blztmc)) {
                        SysWxUser sysWxUser =  wxUserService.selectWxUserByAuth(auth);
                        JjzApplyLog jjzApplyLog = new JjzApplyLog();
                        jjzApplyLog.setType(2);
                        jjzApplyLog.setUserName(sysWxUser.getJsrxm());
                        jjzApplyLog.setWxUserId(sysWxUser.getId());
                        jjzApplyLog.setMsg(jjzResVo.shsbyyms);
                        jjzApplyLog.setApplyTime(new Date());
                        jjzApplyLog.setHphm(jjzResVo.getHphm());
                        jjzApplyLogMapper.insertLog(jjzApplyLog);
                        SysCarInfo carInfo = new SysCarInfo();
                        carInfo.setHphm(hphm);
                        carInfo.setApplyStatus(2);
                        carInfoService.updateCarInfoByHphm(carInfo);
                    }
                }
            } else {
                List<JjzResVo> bzxxRes = JSONArray.parseArray(jsonstr.getString("bzxx"), JjzResVo.class);
                for (JjzResVo jjzResVo : bzxxRes) {
                    //车牌号码
                    String hphm = jjzResVo.getHphm();
                    String blztmc = jjzResVo.getBlztmc();
                    //如果申请成功 修改状态为审核通过
                    if ("审核通过(待生效)".equals(blztmc) || "审核通过(生效中)".equals(blztmc)) {
                        SysCarInfo carInfo = new SysCarInfo();
                        carInfo.setHphm(hphm);
                        carInfo.setYxqs(jjzResVo.getYxqs());
                        carInfo.setYxqz(jjzResVo.getYxqz());
                        carInfo.setApplyStatus(1);
                        carInfoService.updateCarInfoByHphm(carInfo);
                    }
                }
            }
        }
        updateDate();
    }

    public JSONArray getStateList(String auth) {
        JSONArray bzclxx = new JSONArray();
        if (StringUtils.isNotEmpty(auth)) {
            try {
                int n = (int) (Math.random() * 10);
                Thread.sleep(n * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        HashMap header = new HashMap();
        header.put("Authorization", auth);
        String res = HttpUtils.sendPost(RuoYiConfig.getJjzPath() + "/pro/applyRecordController/stateList", "", header);
        JSONObject jsonObject = JSONObject.parseObject(res);
       // log.info("getStateList 返回数据：  {}", jsonObject);

        if (jsonObject.get("code").equals(200)) {
            JSONObject data = jsonObject.getJSONObject("data");
            bzclxx = data.getJSONArray("bzclxx");
        }
        }
        return bzclxx;
    }

    /**
     * 方法六：使用Hutool的ResourceUtil
     * 备注：jar包可用
     *
     * @param fileName
     * @return
     * @throws IOException
     */
    public <T>  List<T> getJjlkList(String fileName, Class<T> object) {
        List<T> list = new ArrayList<>();
        try {
            List<URL> resources = ResourceUtil.getResources(fileName);
            URL resource = resources.get(0);
            InputStreamReader inputStream = new InputStreamReader(resource.openStream());
            String read = IoUtil.read(inputStream);
            list = JSONArray.parseArray(read, object);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    public void checkExpData(){
        List<SysCarInfo> list = carInfoService.selectExpData();
        if(list.size()>0){
            List<Long> ids = list.stream().map(item->{return item.getId();}).collect(Collectors.toList());
            carInfoService.updateCarInfoBatch(ids);
        }
    }

    @Override
    public void updateDate() {

        List<SysCarInfo> list = carInfoService.getUpdateList();
        for (SysCarInfo item : list) {
            SysCarInfo carInfo = new SysCarInfo();
            carInfo.setId(item.getId());
            carInfo.setStartTime(item.getYxqs());
            carInfo.setEndTime(item.getYxqz());
            carInfo.setYxqz(null);
            carInfo.setYxqs(null);
            carInfoService.updateCarInfoDate(carInfo);
        }
    }

    @Override
    public void updateStartEndDate() {
        // 获取当天生效的六环外进京证
        List<ApplyCarVo> list = carInfoService.getTakeEffect(LocalDate.now().atStartOfDay());
        for (ApplyCarVo applyCarVo : list) {
            try {
                int n = (int) (Math.random() * 10);
                Thread.sleep(n * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            JSONArray bzclxx = getStateList(applyCarVo.getAuthorization());
            for (Object o : bzclxx) {
                JSONObject jsonstr = JSONObject.parseObject(o.toString());
                List<JjzResVo> bzxxRes = JSONArray.parseArray(jsonstr.getString("bzxx"), JjzResVo.class);
                for (JjzResVo jjzResVo : bzxxRes) {
                    //车牌号码
                    String hphm = jjzResVo.getHphm();
                    LocalDateTime yxqs = jjzResVo.getYxqs();
                    String blztmc = jjzResVo.getBlztmc();
                    if ("审核通过(生效中)".equals(blztmc)) {
                        if (!applyCarVo.getStartTime().equals(yxqs)) {
                            //如果生效日期发送改变
                            SysCarInfo carInfo = new SysCarInfo();
                            carInfo.setHphm(hphm);
                            carInfo.setStartTime(jjzResVo.getYxqs());
                            carInfo.setEndTime(jjzResVo.getYxqz());
                            carInfoService.updateCarInfoByHphm(carInfo);
                            log.info("取消外当天办理内======》》》》" + hphm);
                        }
                    }
                }
            }
        }
    }

}
